import {UIButton, UIElement, UIInput, UIPanel, UIRow, UIText} from "../../js/threejs/libs/ui.js";

export default class DeviceToolFunctionDialog {
  #id
  #signals

  constructor(displayer) {
    let scope = this
    this.#signals = displayer.signals;
  }

  createFunctionDialog(functionConfig, position) {
    let scope = this

    const length = functionConfig['inputParams']
      .filter(inputParam => inputParam.inputMode.indexOf("opt_input") !== -1)
      .length;
    // 判断：操作输入参数
    if(length <= 0) {
      // 不弹窗直接执行功能
      this.invokeFunction(functionConfig)
      return false
    }

    let functionDialogClass = `dialog function-dialog ${functionConfig.instanceId} ${functionConfig.id}`
    this.#id = functionDialogClass

    if (document.getElementsByClassName(functionDialogClass).length > 0){
      document.getElementsByClassName(functionDialogClass).item(0).style.display = 'block'
      return false;
    }
    let functionDialog = new UIPanel()

    functionDialog.dom.addEventListener('mousedown', ev => {
      ev.stopImmediatePropagation()
      ev.stopPropagation()
    })
    functionDialog.dom.addEventListener('click', ev => {
      ev.stopImmediatePropagation()
      ev.stopPropagation()
    })
    functionDialog.dom.addEventListener('dblclick', ev => {
      ev.stopImmediatePropagation()
      ev.stopPropagation()
    })

    functionDialog.setClass(functionDialogClass)
    this.functionDialog = functionDialog
    /* 设置位置 */
    let p = displayer.transPosition(position)
    let menuP = this.functionPosition(functionDialog, p)
    functionDialog.setStyle('left', [menuP.x + 'px'])
    functionDialog.setStyle('top', [menuP.y + 'px'])

    let viewport = document.getElementById('viewport')
    viewport.appendChild(functionDialog.dom)

    let header = new UIPanel()
    header.setClass('header')
    functionDialog.add(header)
    /* 标题 */
    let title = new UIElement(document.createElement('span'))
    title.setTextContent(functionConfig.name)
    header.add(title)
    /* 关闭按钮 */
    const closeButton = this.closeButton(functionConfig);
    closeButton.dom.addEventListener('mousedown', (e) => {
      this.removeFunction(functionDialog)
    })
    header.add(closeButton)

    functionDialog.add(this.buildFunctionPanel(functionConfig))

    this.#signals.cameraChanged.add(scope.resetPosition, this)
  }

  buildFunctionPanel = (functionConfig) => {
    console.log(functionConfig)

    let funcPanel = new UIPanel()
    funcPanel.setClass('function-panel')
    let paramsPanel = new UIPanel()
    funcPanel.add(paramsPanel)

    let funcButton = new UIButton('执行')
    funcButton.setClass('funcButton')
    funcButton.onClick(() => this.invokeFunction(functionConfig))
    funcPanel.add(funcButton)

    functionConfig['inputParams']
      .filter(inputParam => inputParam.inputMode.indexOf("opt_input") !== -1)
      .map(extendParam => {
        if('int,float,double,long'.includes(extendParam.type)) {
          // 数字类型的数据
          extendParam.formatValue = extendParam.value
        }
        let extendParamRow = new UIRow()
        extendParamRow.dom.style.textAlign = 'right'
        let value = new UIInput(extendParam.formatValue)
        value.setClass('funcParam')
        value.dom.addEventListener('change', function () {
          extendParam.formatValue = value.getValue()
        });
        extendParamRow.add(new UIText(extendParam.name + '：'))
        extendParamRow.add(value)
        paramsPanel.add(extendParamRow)
      })
    return funcPanel
  }

  invokeFunction(func) {
    // 删除功能输入参数中的metadata元素
    func.inputParams.map(input => {
      delete input.metadata
    })
    console.log("执行功能 >>>>> ", func)
    displayer.request.postAction('/device/instance/invokeFunction', func).then((res) => {
      if (res.success) {
        console.log(res.message)
      }
    })
  }

  closeButton = (functionConfig) => {
    // 关闭按钮
    const closeSvg = (function () {
      let svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
      svg.setAttribute('width', 28)
      svg.setAttribute('height', 24)
      let path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
      path.id = 'function-close-btn_' + functionConfig.instanceId + '_' + functionConfig.id
      path.setAttribute('d', 'M 12,12 L 22,22 M 22,12 12,22')
      path.setAttribute('stroke', 'aqua')
      svg.appendChild(path)
      return svg
    })()
    let close = new UIElement(closeSvg)
    close.setPosition('absolute')
    close.setTop('0')
    close.setRight('0')
    close.setCursor('pointer')
    return close
  }
  removeFunction = (functionDialog) => {
    let scope = this
    if (!functionDialog) {
      functionDialog = this.functionDialog
    }
    if (functionDialog === this.functionDialog) {
      this.#signals.cameraChanged.remove(this.resetPosition, this)

      functionDialog.dom.remove()
      functionDialog.remove()
      this.#signals.removeLabel.remove(this.removeFunction, this)
      scope = null
    }
  }
  /* 标签重新定位 */
  timer = null
  resetPosition = () => {
    let scope = this

    this.functionDialog.setStyle('display', ['none'])
    clearTimeout(this.timer)
    this.timer = setTimeout(() => {
      let object = displayer.objectByUuid(this.functionDialog.dom.classList[2])
      if (object) {
        scope.functionDialog.setStyle('display', ['block'])
        let p = displayer.transPosition(object.position)
        let labelP = scope.functionPosition(scope.functionDialog, p)
        scope.functionDialog.setStyle('left', [labelP.x + 'px'])
        scope.functionDialog.setStyle('top', [labelP.y + 'px'])
      }
    }, 400)
  }

  /**
   * 计算menu的平面坐标
   * @param functionDialog
   * @param point 点击位置
   */
  functionPosition = (functionDialog, point) => {
    let functionPosition = {x: point.x, y: point.y}
    // functionDialog的尺寸
    let width = functionDialog.dom.offsetWidth || 0
    let height = functionDialog.dom.offsetHeight || 0

    if (point.x + width > displayer.VIEWPORT_WIDTH) {
      // 右侧超出
      functionPosition.x = displayer.VIEWPORT_WIDTH - width
    }
    if (point.y + height > displayer.VIEWPORT_HEIGHT) {
      // 下侧超出
      functionPosition.y = displayer.VIEWPORT_HEIGHT - height
    }
    if (point.x < 0) {
      // 左侧超出
      functionPosition.x = 0
    }
    if (point.y < 0) {
      // 上侧超出
      functionPosition.y = 0
    }
    return functionPosition;
  }
}